package com.sky.orangehireserver.modules.job_seeker.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sky.orangehireserver.common.domain.Jobs;
import com.sky.orangehireserver.common.domain.Organization;
import com.sky.orangehireserver.common.service.JobsService;
import com.sky.orangehireserver.common.service.OrganizationService;
import com.sky.orangehireserver.exception.BizException;
import com.sky.orangehireserver.modules.job_seeker.dto.SeekerJobQueryDTO;
import com.sky.orangehireserver.modules.job_seeker.service.SeekerJobService;
import com.sky.orangehireserver.modules.job_seeker.vo.SeekerJobBriefVO;
import com.sky.orangehireserver.modules.job_seeker.vo.SeekerJobVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 求职者岗位查询服务实现类
 * 
 * @author sky
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SeekerJobServiceImpl implements SeekerJobService {

    private final JobsService jobsService;
    private final OrganizationService organizationService;

    @Override
    public IPage<SeekerJobBriefVO> getJobPage(SeekerJobQueryDTO queryDTO) {
        log.info("分页查询岗位列表，查询条件：{}", queryDTO);
        
        // 构建查询条件
        LambdaQueryWrapper<Jobs> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Jobs::getStatus, "open") // 只查询开放状态的岗位
                .like(StrUtil.isNotBlank(queryDTO.getTitle()), Jobs::getTitle, queryDTO.getTitle())
                .like(StrUtil.isNotBlank(queryDTO.getLocation()), Jobs::getLocation, queryDTO.getLocation())
                .eq(StrUtil.isNotBlank(queryDTO.getDepartment()), Jobs::getDepartment, queryDTO.getDepartment())
                .eq(StrUtil.isNotBlank(queryDTO.getEmploymentType()), Jobs::getEmploymentType, queryDTO.getEmploymentType())
                .eq(StrUtil.isNotBlank(queryDTO.getSeniority()), Jobs::getSeniority, queryDTO.getSeniority())
                .eq(StrUtil.isNotBlank(queryDTO.getEducation()), Jobs::getEducation, queryDTO.getEducation())
                .eq(StrUtil.isNotBlank(queryDTO.getCurrency()), Jobs::getCurrency, queryDTO.getCurrency())
                .like(StrUtil.isNotBlank(queryDTO.getTags()), Jobs::getTags, queryDTO.getTags());
        
        // 薪资范围查询
        if (queryDTO.getSalaryMin() != null) {
            queryWrapper.ge(Jobs::getSalaryMax, queryDTO.getSalaryMin());
        }
        if (queryDTO.getSalaryMax() != null) {
            queryWrapper.le(Jobs::getSalaryMin, queryDTO.getSalaryMax());
        }
        
        // 排序
        String sortField = queryDTO.getSortField();
        String sortOrder = queryDTO.getSortOrder();
        if (StrUtil.isNotBlank(sortField)) {
            boolean isAsc = "asc".equalsIgnoreCase(sortOrder);
            switch (sortField) {
                case "created_at" -> {
                    if (isAsc) queryWrapper.orderByAsc(Jobs::getCreatedAt);
                    else queryWrapper.orderByDesc(Jobs::getCreatedAt);
                }
                case "salary_min" -> {
                    if (isAsc) queryWrapper.orderByAsc(Jobs::getSalaryMin);
                    else queryWrapper.orderByDesc(Jobs::getSalaryMin);
                }
                case "salary_max" -> {
                    if (isAsc) queryWrapper.orderByAsc(Jobs::getSalaryMax);
                    else queryWrapper.orderByDesc(Jobs::getSalaryMax);
                }
                case "views_count" -> {
                    if (isAsc) queryWrapper.orderByAsc(Jobs::getViewsCount);
                    else queryWrapper.orderByDesc(Jobs::getViewsCount);
                }
                case "applications_count" -> {
                    if (isAsc) queryWrapper.orderByAsc(Jobs::getApplicationsCount);
                    else queryWrapper.orderByDesc(Jobs::getApplicationsCount);
                }
                default -> queryWrapper.orderByDesc(Jobs::getCreatedAt);
            }
        } else {
            queryWrapper.orderByDesc(Jobs::getCreatedAt);
        }
        
        // 分页查询
        Page<Jobs> page = new Page<>(queryDTO.getCurrent(), queryDTO.getSize());
        IPage<Jobs> jobPage = jobsService.page(page, queryWrapper);
        
        // 如果有企业名称查询条件，需要先查询企业
        if (StrUtil.isNotBlank(queryDTO.getCompanyName())) {
            LambdaQueryWrapper<Organization> orgQueryWrapper = new LambdaQueryWrapper<>();
            orgQueryWrapper.like(Organization::getName, queryDTO.getCompanyName())
                    .eq(Organization::getStatus, "active");
            List<Organization> organizations = organizationService.list(orgQueryWrapper);
            
            if (organizations.isEmpty()) {
                // 没有匹配的企业，返回空结果
                IPage<SeekerJobBriefVO> emptyPage = new Page<>(queryDTO.getCurrent(), queryDTO.getSize(), 0);
                emptyPage.setRecords(Collections.emptyList());
                return emptyPage;
            }
            
            List<Long> orgIds = organizations.stream().map(Organization::getId).collect(Collectors.toList());
            queryWrapper.in(Jobs::getOrgId, orgIds);
            
            // 重新查询
            jobPage = jobsService.page(page, queryWrapper);
        }
        
        // 获取企业信息映射
        List<Long> orgIds = jobPage.getRecords().stream()
                .map(Jobs::getOrgId)
                .distinct()
                .collect(Collectors.toList());
        
        Map<Long, Organization> orgMap = organizationService.listByIds(orgIds).stream()
                .collect(Collectors.toMap(Organization::getId, org -> org));
        
        // 转换为VO
        IPage<SeekerJobBriefVO> voPage = new Page<>(jobPage.getCurrent(), jobPage.getSize(), jobPage.getTotal());
        List<SeekerJobBriefVO> voList = jobPage.getRecords().stream()
                .map(job -> convertToBriefVO(job, orgMap.get(job.getOrgId())))
                .collect(Collectors.toList());
        voPage.setRecords(voList);
        
        return voPage;
    }

    @Override
    public SeekerJobVO getJobById(Long jobId) {
        log.info("查询岗位详情，岗位ID：{}", jobId);
        
        Jobs job = jobsService.getById(jobId);
        if (job == null) {
            throw new BizException("JOB_NOT_FOUND", "岗位不存在");
        }
        
        // 检查岗位状态
        if (!"open".equals(job.getStatus())) {
            throw new BizException("JOB_NOT_AVAILABLE", "岗位暂不可用");
        }
        
        // 获取企业信息
        Organization organization = organizationService.getById(job.getOrgId());
        if (organization == null || !"active".equals(organization.getStatus())) {
            throw new BizException("ORGANIZATION_NOT_AVAILABLE", "企业暂不可用");
        }
        
        return convertToVO(job, organization);
    }

    @Override
    public List<SeekerJobBriefVO> getHotJobs(Integer limit) {
        log.info("查询热门岗位列表，数量限制：{}", limit);
        
        if (limit == null || limit <= 0) {
            limit = 10;
        }
        
        LambdaQueryWrapper<Jobs> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Jobs::getStatus, "open")
                .orderByDesc(Jobs::getViewsCount)
                .orderByDesc(Jobs::getApplicationsCount)
                .orderByDesc(Jobs::getCreatedAt)
                .last("LIMIT " + limit);
        
        List<Jobs> jobs = jobsService.list(queryWrapper);
        return convertToBriefVOList(jobs);
    }

    @Override
    public List<SeekerJobBriefVO> getLatestJobs(Integer limit) {
        log.info("查询最新岗位列表，数量限制：{}", limit);
        
        if (limit == null || limit <= 0) {
            limit = 10;
        }
        
        LambdaQueryWrapper<Jobs> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Jobs::getStatus, "open")
                .orderByDesc(Jobs::getCreatedAt)
                .last("LIMIT " + limit);
        
        List<Jobs> jobs = jobsService.list(queryWrapper);
        return convertToBriefVOList(jobs);
    }

    @Override
    public IPage<SeekerJobBriefVO> getJobsByOrgId(Long orgId, Long current, Long size) {
        log.info("根据企业ID查询岗位列表，企业ID：{}，当前页：{}，每页大小：{}", orgId, current, size);
        
        // 检查企业是否存在且可用
        Organization organization = organizationService.getById(orgId);
        if (organization == null || !"active".equals(organization.getStatus())) {
            throw new BizException("ORGANIZATION_NOT_AVAILABLE", "企业暂不可用");
        }
        
        LambdaQueryWrapper<Jobs> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Jobs::getOrgId, orgId)
                .eq(Jobs::getStatus, "open")
                .orderByDesc(Jobs::getCreatedAt);
        
        Page<Jobs> page = new Page<>(current, size);
        IPage<Jobs> jobPage = jobsService.page(page, queryWrapper);
        
        // 转换为VO
        IPage<SeekerJobBriefVO> voPage = new Page<>(jobPage.getCurrent(), jobPage.getSize(), jobPage.getTotal());
        List<SeekerJobBriefVO> voList = jobPage.getRecords().stream()
                .map(job -> convertToBriefVO(job, organization))
                .collect(Collectors.toList());
        voPage.setRecords(voList);
        
        return voPage;
    }

    @Override
    public IPage<SeekerJobBriefVO> getJobsByLocation(String location, Long current, Long size) {
        log.info("根据城市查询岗位列表，城市：{}，当前页：{}，每页大小：{}", location, current, size);
        
        LambdaQueryWrapper<Jobs> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Jobs::getLocation, location)
                .eq(Jobs::getStatus, "open")
                .orderByDesc(Jobs::getCreatedAt);
        
        Page<Jobs> page = new Page<>(current, size);
        IPage<Jobs> jobPage = jobsService.page(page, queryWrapper);
        
        // 获取企业信息映射
        List<Long> orgIds = jobPage.getRecords().stream()
                .map(Jobs::getOrgId)
                .distinct()
                .collect(Collectors.toList());
        
        Map<Long, Organization> orgMap = organizationService.listByIds(orgIds).stream()
                .collect(Collectors.toMap(Organization::getId, org -> org));
        
        // 转换为VO
        IPage<SeekerJobBriefVO> voPage = new Page<>(jobPage.getCurrent(), jobPage.getSize(), jobPage.getTotal());
        List<SeekerJobBriefVO> voList = jobPage.getRecords().stream()
                .map(job -> convertToBriefVO(job, orgMap.get(job.getOrgId())))
                .collect(Collectors.toList());
        voPage.setRecords(voList);
        
        return voPage;
    }

    @Override
    public IPage<SeekerJobBriefVO> getJobsByTag(String tag, Long current, Long size) {
        log.info("根据标签查询岗位列表，标签：{}，当前页：{}，每页大小：{}", tag, current, size);
        
        LambdaQueryWrapper<Jobs> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(Jobs::getTags, tag)
                .eq(Jobs::getStatus, "open")
                .orderByDesc(Jobs::getCreatedAt);
        
        Page<Jobs> page = new Page<>(current, size);
        IPage<Jobs> jobPage = jobsService.page(page, queryWrapper);
        
        // 获取企业信息映射
        List<Long> orgIds = jobPage.getRecords().stream()
                .map(Jobs::getOrgId)
                .distinct()
                .collect(Collectors.toList());
        
        Map<Long, Organization> orgMap = organizationService.listByIds(orgIds).stream()
                .collect(Collectors.toMap(Organization::getId, org -> org));
        
        // 转换为VO
        IPage<SeekerJobBriefVO> voPage = new Page<>(jobPage.getCurrent(), jobPage.getSize(), jobPage.getTotal());
        List<SeekerJobBriefVO> voList = jobPage.getRecords().stream()
                .map(job -> convertToBriefVO(job, orgMap.get(job.getOrgId())))
                .collect(Collectors.toList());
        voPage.setRecords(voList);
        
        return voPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void incrementViewsCount(Long jobId) {
        Jobs job = jobsService.getById(jobId);
        if (job != null) {
            Jobs updateJob = new Jobs();
            updateJob.setId(jobId);
            updateJob.setViewsCount((job.getViewsCount() == null ? 0 : job.getViewsCount()) + 1);
            updateJob.setUpdatedAt(LocalDateTime.now());
            jobsService.updateById(updateJob);
        }
    }

    @Override
    public Map<String, Object> getJobStatistics() {
        log.info("查询岗位统计信息");
        
        Map<String, Object> statistics = new HashMap<>();
        
        // 总岗位数
        LambdaQueryWrapper<Jobs> totalWrapper = new LambdaQueryWrapper<>();
        totalWrapper.eq(Jobs::getStatus, "open");
        long totalJobs = jobsService.count(totalWrapper);
        statistics.put("totalJobs", totalJobs);
        
        // 今日新增岗位数
        LambdaQueryWrapper<Jobs> todayWrapper = new LambdaQueryWrapper<>();
        todayWrapper.eq(Jobs::getStatus, "open")
                .ge(Jobs::getCreatedAt, LocalDateTime.now().toLocalDate().atStartOfDay());
        long todayJobs = jobsService.count(todayWrapper);
        statistics.put("todayJobs", todayJobs);
        
        // 热门城市统计（前10）
        // TODO: 这里需要使用原生SQL或者其他方式进行GROUP BY统计
        // 暂时返回空列表
        statistics.put("hotCities", Collections.emptyList());
        
        // 热门标签统计（前10）
        // TODO: 这里需要解析tags字段并进行统计
        statistics.put("hotTags", Collections.emptyList());
        
        return statistics;
    }

    @Override
    public List<String> getHotSearchKeywords(Integer limit) {
        log.info("查询热门搜索关键词，数量限制：{}", limit);
        
        // TODO: 这里应该基于用户搜索历史进行统计
        // 暂时返回一些默认的热门关键词
        List<String> hotKeywords = Arrays.asList(
                "Java", "Python", "前端", "后端", "产品经理", 
                "UI设计师", "数据分析", "运营", "测试", "架构师"
        );
        
        if (limit != null && limit > 0 && limit < hotKeywords.size()) {
            return hotKeywords.subList(0, limit);
        }
        
        return hotKeywords;
    }

    @Override
    public List<SeekerJobBriefVO> getRecommendedJobs(Long userId, Integer limit) {
        log.info("查询推荐岗位，用户ID：{}，数量限制：{}", userId, limit);
        
        if (limit == null || limit <= 0) {
            limit = 10;
        }
        
        // TODO: 这里应该基于用户的浏览历史、投递历史等进行个性化推荐
        // 暂时返回热门岗位作为推荐
        return getHotJobs(limit);
    }

    /**
     * 批量转换为简要VO列表
     */
    private List<SeekerJobBriefVO> convertToBriefVOList(List<Jobs> jobs) {
        if (jobs.isEmpty()) {
            return Collections.emptyList();
        }
        
        // 获取企业信息映射
        List<Long> orgIds = jobs.stream()
                .map(Jobs::getOrgId)
                .distinct()
                .collect(Collectors.toList());
        
        Map<Long, Organization> orgMap = organizationService.listByIds(orgIds).stream()
                .collect(Collectors.toMap(Organization::getId, org -> org));
        
        return jobs.stream()
                .map(job -> convertToBriefVO(job, orgMap.get(job.getOrgId())))
                .collect(Collectors.toList());
    }

    /**
     * 将Jobs实体转换为SeekerJobVO
     */
    private SeekerJobVO convertToVO(Jobs job, Organization organization) {
        SeekerJobVO vo = BeanUtil.copyProperties(job, SeekerJobVO.class);
        
        // 设置企业信息
        if (organization != null) {
            vo.setOrgName(organization.getName());
            vo.setOrgLogoUrl(organization.getLogoUrl());
        }
        
        // 设置各种名称
        vo.setEmploymentTypeName(getEmploymentTypeName(job.getEmploymentType()));
        vo.setSeniorityName(getSeniorityName(job.getSeniority()));
        vo.setEducationName(getEducationName(job.getEducation()));
        vo.setStatusName(getStatusName(job.getStatus()));
        
        // 设置薪资范围显示
        vo.setSalaryRange(formatSalaryRange(job.getSalaryMin(), job.getSalaryMax(), job.getCurrency()));
        
        // 设置标签列表
        vo.setTagList(parseTagList(job.getTags()));
        
        return vo;
    }

    /**
     * 将Jobs实体转换为SeekerJobBriefVO
     */
    private SeekerJobBriefVO convertToBriefVO(Jobs job, Organization organization) {
        SeekerJobBriefVO vo = BeanUtil.copyProperties(job, SeekerJobBriefVO.class);
        
        // 设置企业信息
        if (organization != null) {
            vo.setOrgName(organization.getName());
            vo.setOrgLogoUrl(organization.getLogoUrl());
        }
        
        // 设置各种名称
        vo.setEmploymentTypeName(getEmploymentTypeName(job.getEmploymentType()));
        vo.setSeniorityName(getSeniorityName(job.getSeniority()));
        vo.setEducationName(getEducationName(job.getEducation()));
        
        // 设置薪资范围显示
        vo.setSalaryRange(formatSalaryRange(job.getSalaryMin(), job.getSalaryMax(), job.getCurrency()));
        
        // 设置标签列表
        vo.setTagList(parseTagList(job.getTags()));
        
        return vo;
    }

    /**
     * 获取工作类型名称
     */
    private String getEmploymentTypeName(String employmentType) {
        if (employmentType == null) return null;
        return switch (employmentType) {
            case "full_time" -> "全职";
            case "part_time" -> "兼职";
            case "intern" -> "实习";
            case "contract" -> "合同工";
            default -> employmentType;
        };
    }

    /**
     * 获取经验要求名称
     */
    private String getSeniorityName(String seniority) {
        if (seniority == null) return null;
        return switch (seniority) {
            case "junior" -> "初级";
            case "mid" -> "中级";
            case "senior" -> "高级";
            default -> seniority;
        };
    }

    /**
     * 获取学历要求名称
     */
    private String getEducationName(String education) {
        if (education == null) return null;
        return switch (education) {
            case "bachelor" -> "本科";
            case "master" -> "硕士";
            case "phd" -> "博士";
            case "none" -> "不限";
            default -> education;
        };
    }

    /**
     * 获取状态名称
     */
    private String getStatusName(String status) {
        if (status == null) return null;
        return switch (status) {
            case "draft" -> "草稿";
            case "open" -> "招聘中";
            case "closed" -> "已关闭";
            default -> status;
        };
    }

    /**
     * 格式化薪资范围
     */
    private String formatSalaryRange(java.math.BigDecimal salaryMin, java.math.BigDecimal salaryMax, String currency) {
        if (salaryMin == null && salaryMax == null) {
            return "面议";
        }
        
        String currencySymbol = "CNY".equals(currency) ? "" : (currency + " ");
        
        if (salaryMin != null && salaryMax != null) {
            return String.format("%s%dK-%dK", currencySymbol, salaryMin.intValue() / 1000, salaryMax.intValue() / 1000);
        } else if (salaryMin != null) {
            return String.format("%s%dK+", currencySymbol, salaryMin.intValue() / 1000);
        } else {
            return String.format("%s%dK以下", currencySymbol, salaryMax.intValue() / 1000);
        }
    }

    /**
     * 解析标签列表
     */
    private List<String> parseTagList(String tags) {
        if (StrUtil.isBlank(tags)) {
            return Collections.emptyList();
        }
        
        return Arrays.stream(tags.split(","))
                .map(String::trim)
                .filter(StrUtil::isNotBlank)
                .collect(Collectors.toList());
    }
}